/*
 * FileName:       app_dev_08.c
 * Author:         Kingsea  Version: v1.0  Date: 2019-8-8
 * Description:    
 * History:        
 *     <author>   	<version>    	<time>    	<desc>
 *     Kingsea   	v1.0    	2019-8-8    
 */
#include "main.h"
#include "app_asyn_usertask.h"
#include "CodeOfRunningDef.h"
#include "app_dev_08.h"
/****************************************************/
#if (defined APP_DEV_08_EN) && (APP_DEV_08_EN>0)
////
#define DEV_TYPE_AS_AUTOWATERING (0x08+1)
#define PIN_SWITCH_WATER1 14
#define PIN_SWITCH_WATER2 16
#define PIN_MOTOR_WATER1 19
#define PIN_MOTOR_WATER2 20

#define PIN_MOTOR_WATER1_ACTIVE 	0
#define PIN_MOTOR_WATER2_ACTIVE 	0
#define PIN_SWITCH_WATER1_DEFAULT 	1
#define PIN_SWITCH_WATER2_DEFAULT 	1

#define MOTOR_WATER1_EN(bEn) (((bEn)==PIN_MOTOR_WATER1_ACTIVE)?nrf_gpio_pin_set(PIN_MOTOR_WATER1):nrf_gpio_pin_clear(PIN_MOTOR_WATER1))
#define MOTOR_WATER2_EN(bEn) (((bEn)==PIN_MOTOR_WATER2_ACTIVE)?nrf_gpio_pin_set(PIN_MOTOR_WATER2):nrf_gpio_pin_clear(PIN_MOTOR_WATER2))


//////////////////////////////////////////////////////////////////////////
static uint32_t m_AutoWatering_TotalCnt;
static uint32_t m_AutoWatering_ChEnMask;
static bool sAct_DelayDebounce(TickType_t nTicks, uint32_t pin_in, uint32_t pin_inLevel)
{
	bool bSuccess;
	TickType_t i;
	bSuccess = true;
	for (i=0; i<nTicks; i++)
	{
		if (nrf_gpio_pin_read(pin_in) != pin_inLevel)
		{
			bSuccess = false;
			break;
		}
		if (AS_CheckCancelAct()) break;
		vTaskDelay(1);
	}
	return bSuccess;
}
static bool sAct_Watering(uint32_t pin_in, uint32_t pin_inActiveLevel, uint32_t pin_out, uint32_t pin_outActiveLevel)
{
	bool bSuccess = true;
	if (	(nrf_gpio_pin_read(pin_in) == pin_inActiveLevel)
		&& 	(m_AutoWatering_ChEnMask & (1<<pin_out))
		&&  (sAct_DelayDebounce(APP_TIMER_TICKS(3000.0), pin_in, pin_inActiveLevel)))
	{
		TickType_t xTimeNow, xTimeoutTick;
		xTimeoutTick = APP_TIMER_TICKS(20000.0);
		xTimeNow = xTaskGetTickCount();
		((1)==pin_outActiveLevel)?nrf_gpio_pin_set(pin_out):nrf_gpio_pin_clear(pin_out);
		while (!AS_CheckCancelAct())
		{
			if (nrf_gpio_pin_read(pin_in) != pin_inActiveLevel)
			{
				nrf_gpio_pin_toggle(pin_out);
				if (sAct_DelayDebounce(APP_TIMER_TICKS(10.0), pin_in, !pin_inActiveLevel))
				{
					// success
					m_AutoWatering_TotalCnt++;
					break;
				}
				nrf_gpio_pin_toggle(pin_out);
			}
			if (((xTaskGetTickCount()-xTimeNow)>xTimeoutTick))
			{
				// fail
				m_AutoWatering_ChEnMask &= ~(1<<pin_out);
				if(m_AutoWatering_ChEnMask == 0) bSuccess = false;
				break;
			}
			vTaskDelay(1);
		}
		((0)==pin_outActiveLevel)?nrf_gpio_pin_set(pin_out):nrf_gpio_pin_clear(pin_out);
		NRF_LOG_DEBUG("Water 1 loop spend time= %d ms", (xTaskGetTickCount()-xTimeNow)*1000/configTICK_RATE_HZ);
		async_ret_printf("%d 0x%X", m_AutoWatering_TotalCnt, m_AutoWatering_ChEnMask);
	}
	return bSuccess;
}
static bool Act_Set_Auto_Watering()
{
	bool bSuccess = true;
	while (!AS_CheckCancelAct())
	{
		bSuccess = sAct_Watering(PIN_SWITCH_WATER1, !PIN_SWITCH_WATER1_DEFAULT, PIN_MOTOR_WATER1, PIN_MOTOR_WATER1_ACTIVE);
		if(!bSuccess) break;
		bSuccess = sAct_Watering(PIN_SWITCH_WATER2, !PIN_SWITCH_WATER2_DEFAULT, PIN_MOTOR_WATER2, PIN_MOTOR_WATER2_ACTIVE);
		if(!bSuccess) break;
		vTaskDelay(1);
	}
	return bSuccess;
}

static void Act_AutoWatering_Init()
{
	nrf_gpio_cfg_input(PIN_SWITCH_WATER1, (nrf_gpio_pin_pull_t)NRF_GPIO_PIN_PULLUP);
	nrf_gpio_cfg_input(PIN_SWITCH_WATER2, (nrf_gpio_pin_pull_t)NRF_GPIO_PIN_PULLUP);
	MOTOR_WATER1_EN(0);
	nrf_gpio_cfg_output(PIN_MOTOR_WATER1);
	MOTOR_WATER2_EN(0);
	nrf_gpio_cfg_output(PIN_MOTOR_WATER2);
	m_AutoWatering_TotalCnt = 0;
	m_AutoWatering_ChEnMask = (1<<PIN_MOTOR_WATER1)+(1<<PIN_MOTOR_WATER2);
	{
		extern BaseType_t sys_command_send(const char * pszcmd, BaseType_t * const pxHigherPriorityTaskWoken);
		sys_command_send("#iopen", NULL);
		AS_setDoAction(A_Set_Auto_Watering, NULL);
	}
	NRF_LOG_DEBUG("%s()", (uint32_t)__func__);
}

static bool Act_AutoWatering_Do(uint32_t uActID, char * pArgString)
{
	bool bSuccess = false;
	switch (uActID)
	{
	case A_Set_Auto_Watering:
		bSuccess = Act_Set_Auto_Watering();
		break;
	default:
		break;
	}
	return bSuccess;
}

////
const APP_DEV_INTERFACE_ST m_APP_DEV_08_IF = {
    Act_AutoWatering_Init,
    Act_AutoWatering_Do
};
#endif /*(defined APP_DEV_08_EN) && (APP_DEV_08_EN>0)*/
// file end
//// 
